#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Pgpool管理器模块
提供Pgpool连接池的安装、配置和管理功能
"""

import os
import hashlib
import getpass
from typing import Optional, List

from ..core.utils import (
    logger,
    run_command,
    is_windows,
    confirm_action,
    get_input_with_default
)
from ..core import config

class PgpoolManager:
    """Pgpool连接池管理类"""
    
    def __init__(self):
        self.service_name = "pgpool2"
        if is_windows():
            self.config_dir = "C:\\Program Files\\pgpool\\etc"
        else:
            self.config_dir = "/etc/pgpool2"
        
    def install(self):
        """安装Pgpool连接池"""
        logger.info("正在安装最新版本的pgpool")
        
        try:
            run_command(["sudo", "apt", "update"])
            run_command(["sudo", "apt", "install", "-y", "pgpool2"])
            logger.info("pgpool安装成功")
        except Exception as e:
            logger.error(f"安装pgpool时出错: {e}")
    
    def uninstall(self):
        """卸载Pgpool连接池"""
        if not confirm_action("确定要卸载pgpool吗?", False):
            logger.info("已取消卸载pgpool")
            return
            
        logger.info("正在卸载pgpool")
        
        try:
            run_command(["sudo", "systemctl", "stop", self.service_name])
            run_command(["sudo", "apt", "purge", "-y", "pgpool2"])
            run_command(["sudo", "apt", "autoremove", "-y"])
            run_command(["sudo", "rm", "-rf", "/etc/pgpool2", "/var/lib/pgpool2"])
            logger.info("pgpool卸载完成")
        except Exception as e:
            logger.error(f"卸载pgpool时出错: {e}")
    
    def start(self):
        """启动Pgpool服务"""
        logger.info("正在启动pgpool")
        
        try:
            run_command(["sudo", "systemctl", "start", self.service_name])
            logger.info("pgpool已启动")
        except Exception as e:
            logger.error(f"启动pgpool时出错: {e}")
    
    def stop(self):
        """停止Pgpool服务"""
        logger.info("正在停止pgpool")
        
        try:
            run_command(["sudo", "systemctl", "stop", self.service_name])
            logger.info("pgpool已停止")
        except Exception as e:
            logger.error(f"停止pgpool时出错: {e}")
    
    def restart(self):
        """重启Pgpool服务"""
        logger.info("正在重启pgpool")
        
        try:
            run_command(["sudo", "systemctl", "restart", self.service_name])
            logger.info("pgpool已重启")
        except Exception as e:
            logger.error(f"重启pgpool时出错: {e}")
    
    def reload(self):
        """重新加载Pgpool配置"""
        logger.info("正在重新加载pgpool配置")
        
        try:
            run_command(["sudo", "systemctl", "reload", self.service_name])
            logger.info("pgpool配置已重新加载")
        except Exception as e:
            logger.error(f"重新加载pgpool配置时出错: {e}")
    
    def status(self):
        """查看Pgpool状态"""
        logger.info("正在显示连接池节点信息")
        
        try:
            # 写入SQL命令到文件，使用临时目录
            sql_file_path = os.path.join(config.TEMP_DIR, "pgpool_commands.sql")
            
            # 删除旧的SQL文件(如果存在)
            if os.path.exists(sql_file_path):
                os.remove(sql_file_path)
                
            with open(sql_file_path, "w") as f:
                f.write("\\x\n")  # 切换到扩展模式
                f.write("SHOW pool_nodes;\n")  # 执行查询
                
            # 设置文件权限为644
            os.chmod(sql_file_path, 0o777)
            
            # Windows上不需要更改所有者
            if not is_windows():
                run_command(["sudo", "chown", "postgres:postgres", sql_file_path])
            
            # 通过psql执行文件中的命令，使用配置中的端口号
            result = run_command(
                ["sudo", "-u", "postgres", "psql", "-h", "localhost", 
                 "-p", str(config.DEFAULT_PGPOOL_PORT), 
                 "-U", "postgres", "-f", sql_file_path],
                capture_output=True
            )
            print(result.stdout)  # 输出结果
            
            # 清理临时文件
            try:
                os.remove(sql_file_path)
            except:
                pass
        except Exception as e:
            logger.error(f"获取pool_nodes信息时出错: {e}")
            
        logger.info("pgpool运行状态")
        run_command(["sudo", "systemctl", "status", self.service_name])
    
    def show_config(self):
        """显示Pgpool配置信息"""
        logger.info(f"pgpool配置目录: {self.config_dir}")
    
    def pcp_attach_node(self):
        """将节点加回集群"""
        nodeID = get_input_with_default("请输入要加回集群的节点ID", "")
        
        if not nodeID:
            logger.error("节点ID不能为空")
            return
            
        try:
            run_command([
                "sudo", "pcp_attach_node",
                "-h", "localhost", "-p", str(config.DEFAULT_PCP_PORT), "-w", "-n", nodeID
            ])
            logger.info(f"节点 {nodeID} 已成功加入集群")
        except Exception as e:
            logger.error(f"将节点加入集群时出错: {e}")
    
    def pcp_detach_node(self):
        """从集群分离节点"""
        nodeID = get_input_with_default("请输入要从集群分离的节点ID", "")
        
        if not nodeID:
            logger.error("节点ID不能为空")
            return
            
        try:
            run_command([
                "sudo", "pcp_detach_node",
                "-h", "localhost", "-p", str(config.DEFAULT_PCP_PORT), "-w", "-n", nodeID
            ])
            logger.info(f"节点 {nodeID} 已成功从集群分离")
        except Exception as e:
            logger.error(f"从集群分离节点时出错: {e}")
    
    def create_pcp_pass_and_update_conf(self):
        """为当前用户创建.pcppass并写入pcp.conf"""
        # 获取当前用户和输入的密码
        current_user = getpass.getuser()
        pcp_password = getpass.getpass(prompt=f"请输入{current_user}用户的密码: ")
        
        if not pcp_password:
            logger.error("密码不能为空")
            return
            
        # 使用hashlib生成MD5哈希值
        hashed_password = hashlib.md5(pcp_password.encode()).hexdigest()
        
        # 创建并写入~/.pcppass文件
        pcppass_path = os.path.expanduser(config.PCP_PASS_FILE)
        try:
            with open(pcppass_path, "w") as f:
                f.write(f"localhost:{config.DEFAULT_PCP_PORT}:{current_user}:{pcp_password}\n")
                
            # 设置文件权限为600
            os.chmod(pcppass_path, 0o600)
            logger.info(f"已成功创建并设置权限为600: {pcppass_path}")
        except Exception as e:
            logger.error(f"创建 {pcppass_path} 时出错: {e}")
            return
            
        # 更新/etc/pgpool2/pcp.conf文件
        pcp_conf_path = os.path.join(self.config_dir, "pcp.conf")
        try:
            if not os.path.exists(pcp_conf_path):
                logger.error(f"配置文件 {pcp_conf_path} 不存在")
                return
                
            with open(pcp_conf_path, "a") as f:
                f.write(f"{current_user}:{hashed_password}\n")
                
            logger.info(f"已成功更新 {pcp_conf_path}")
        except Exception as e:
            logger.error(f"更新 {pcp_conf_path} 时出错: {e}") 